/**
 * @p.md
 * 
 * Props 类，用于配置 Actor 的创建属性
 */
import { Actor, fromFunc } from './actor';
import { ActorSystem } from './actorSystem';
import { PID } from './pid';
import { RootContext } from './rootContext';
import { DefaultActorProcess } from './defaultActorProcess';
import { Dispatchers, Dispatcher } from './dispatcher';
import { Supervisors, SupervisorDirective } from './supervision';
import { Context } from './context';
import { ProcessRegistry } from './processRegistry';

/**
 * 中间件接口，用于拦截和处理消息
 */
export interface Middleware {
  onReceive(next: (context: any) => void): (context: any) => void;
}

/**
 * 监督者接口，定义了处理 Actor 故障的方法
 */
export interface Supervisor {
  handleFailure(pid: PID, reason: Error): SupervisorDirective;
}

/**
 * 默认监督者实现，总是重启 Actor
 */
export class DefaultSupervisor implements Supervisor {
  handleFailure(pid: PID, reason: Error): SupervisorDirective {
    console.warn(`[DefaultSupervisor] Actor ${pid.id} failed:`, reason);
    // 返回重启指令
    return SupervisorDirective.Restart;
  }
}

/**
 * 邮箱接口，管理 Actor 的消息队列
 */
export interface Mailbox {
  postMessage(message: any): void;
  postSystemMessage(message: any): void;
  registerHandlers(invoker: any, dispatcher: Dispatcher): void;
  start(): void;
}

/**
 * Actor 生产者函数类型
 */
export type ProducerFn = () => Actor;

/**
 * Mailbox 生产者函数类型
 */
export type MailboxProducerFn = () => Mailbox;

/**
 * Props 类，包含创建 Actor 的配置信息
 */
export class Props {
  /**
   * Actor 生产函数
   */
  readonly producer: () => Actor;
  
  /**
   * 邮箱生产函数
   */
  readonly mailboxProducer?: () => any;
  
  /**
   * 调度器
   */
  readonly dispatcher?: Dispatcher;
  
  /**
   * 监督策略
   */
  readonly supervisor?: Supervisor;
  
  /**
   * 构造函数
   * @param producer Actor 生产函数
   * @param mailboxProducer 邮箱生产函数
   * @param dispatcher 调度器
   * @param supervisor 监督策略
   */
  constructor(
    producer: () => Actor,
    mailboxProducer?: () => any,
    dispatcher?: Dispatcher,
    supervisor?: Supervisor
  ) {
    this.producer = producer;
    this.mailboxProducer = mailboxProducer;
    this.dispatcher = dispatcher;
    this.supervisor = supervisor;
  }
  
  /**
   * 创建一个带有指定邮箱生产函数的新 Props
   * @param producer 邮箱生产函数
   * @returns 新的 Props 实例
   */
  withMailbox(producer: () => any): Props {
    return new Props(
      this.producer,
      producer,
      this.dispatcher,
      this.supervisor
    );
  }
  
  /**
   * 创建一个带有指定调度器的新 Props
   * @param dispatcher 调度器
   * @returns 新的 Props 实例
   */
  withDispatcher(dispatcher: Dispatcher): Props {
    return new Props(
      this.producer,
      this.mailboxProducer,
      dispatcher,
      this.supervisor
    );
  }
  
  /**
   * 创建一个带有指定监督策略的新 Props
   * @param supervisor 监督策略
   * @returns 新的 Props 实例
   */
  withSupervisor(supervisor: Supervisor): Props {
    return new Props(
      this.producer,
      this.mailboxProducer,
      this.dispatcher,
      supervisor
    );
  }
  
  /**
   * 从 Actor 生产函数创建 Props
   * @param producer Actor 生产函数
   * @returns 新的 Props 实例
   */
  static fromProducer(producer: () => Actor): Props {
    return new Props(producer);
  }
  
  /**
   * 从函数创建 Props，将函数包装为 Actor
   * @param fn 函数
   * @returns 新的 Props 实例
   */
  static fromFunc(fn: (context: Context) => void): Props {
    return this.fromProducer(() => fromFunc(fn));
  }
  
  /**
   * 创建 Actor 实例并返回 PID
   * @param system Actor 系统
   * @param name Actor 名称
   * @param parent 父上下文
   * @returns Actor 的 PID
   */
  spawn(system: ActorSystem, name: string, parent: RootContext): PID {
    // 创建 Actor 实例
    const actor = this.producer();
    
    // 获取进程注册表实例
    const processRegistry = ProcessRegistry.getInstance();
    
    // 创建 PID
    const pid = new PID(processRegistry.address(), name);
    
    // 创建 Actor 进程
    const process = new DefaultActorProcess(actor, this, system, pid);
    
    // 注册进程并返回 PID
    processRegistry.add(process, name);
    return pid;
  }
} 